package com.xj.socket.tcp.nio.server;

import org.apache.log4j.Logger;

import java.io.IOException;

/**
 * 此类提供ReadWriteSelector的存储池，可以通过getReadWriteSelector()方法获取读写选择器
 * @author xiajun
 * 日期 2013-02-27
 */
public class ReadWritePool {
	private final static Logger log=Logger.getLogger(ReadWritePool.class);
	private static  int size=1;
	/**
	 * 读写Selector的存放数组
	 */
	private static ReadWriteSelector [] selectors=null;
	/**
	 * 选择Selector的凭证 用来%运算
	 */
	private static int count=0;
	private ReadWritePool(){}
	static{
		size=Runtime.getRuntime().availableProcessors();//获取cpu总核数作为读写Selector的总数
		size=size>4?4:size;
		try {
			createSelector();
		} catch (IOException e) {
			e.printStackTrace();
			log.error("创建ReadWriteSelector时发生致命错误。",e);
		}
	}
	/**
	 * 创建读写Selector实例
	 * @throws java.io.IOException
	 */
	private static void createSelector() throws IOException{
		selectors=new ReadWriteSelector[size];
		for (int i = 0; i < size; i++) {
			selectors[i]=new ReadWriteSelector();
		}
	}
	/**
	 * 获取读写Selector的方法，此方法将会依据%运算平行分配
	 * @return ReadWriteSelector
	 * @throws java.io.IOException
	 */
	public synchronized static ReadWriteSelector getReadWriteSelector() throws IOException{
		int i=count%size;
		ReadWriteSelector s=selectors[i];
		if(s!=null&&!s.getSelector().isOpen()){
			selectors[i]=new ReadWriteSelector();
			s=selectors[i];
		}
		count++;
		if(count==Integer.MAX_VALUE-1){
			count=0;
		}
		return s;
	}
	/**
	 * 获取读写Selector的总个数
	 * @return int
	 */
	public static int getSize() {
		return size;
	}
	
}
